﻿//Copyright (C) 2009  Jaco (ScionBot.com)

//This program is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using Microsoft.VisualBasic;

namespace Scion.Library.Underlying
{
    /// <summary>
    /// Speed is of the essence in a Colour Bot. This function locks the canvas into memory for a much
    /// faster screen reading.
    /// </summary>
    public class BufferedImage
    {
        public System.Drawing.Bitmap image;
        public BitmapData bitmapData;
        public int bytesPerPixel = 4;
        public byte[] imageBytes;
        public int imageWidth;
        public int imageHeight;
        public int imageStride;
        public Size imageSize;

        public BufferedImage(Bitmap bmp)
        {
            image = bmp;
            bitmapData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);
            imageBytes = new byte[bitmapData.Width * bitmapData.Height * bytesPerPixel];
            System.Runtime.InteropServices.Marshal.Copy(bitmapData.Scan0, imageBytes, 0, bitmapData.Width * bitmapData.Height * bytesPerPixel);
            imageWidth = bitmapData.Width;
            imageHeight = bitmapData.Height;
            imageStride = bitmapData.Stride;
            imageSize = new Size(imageWidth, imageHeight);
            image.UnlockBits(bitmapData);
        }

        public Color GetPixel(int x, int y)
        {
            if ((x > imageWidth) || (y > imageHeight) || (((imageStride * y) + (bytesPerPixel * x) + 2) > (imageBytes.Length -1)))
                return new System.Drawing.Color();
            int r; int g; int b;
            r = imageBytes[(imageStride * y) + (bytesPerPixel * x) + 2];
            g = imageBytes[(imageStride * y) + (bytesPerPixel * x) + 1];
            b = imageBytes[(imageStride * y) + (bytesPerPixel * x)];
            return System.Drawing.Color.FromArgb(r, g, b);
        }

        public void GetPixel(int x, int y, out int r, out int g, out int b)
        {
            r = (imageBytes[(imageStride * y) + (bytesPerPixel * x) + 2]);
            g = (imageBytes[(imageStride * y) + (bytesPerPixel * x) + 1]);
            b = (imageBytes[(imageStride * y) + (bytesPerPixel * x)]);
        }

        public bool SetPixel(int x, int y, Color col)
        {
            if ((x > imageWidth) || (y > imageHeight) || (((imageStride * y) + (bytesPerPixel * x) + 2) > (imageBytes.Length - 1)))
                return false;
            imageBytes[(imageStride * y) + (bytesPerPixel * x) + 2] = (byte)col.R;
            imageBytes[(imageStride * y) + (bytesPerPixel * x) + 1] = (byte)col.G;
            imageBytes[(imageStride * y) + (bytesPerPixel * x)] = (byte)col.B;
            return true;
        }

        public bool SetPixel(int x, int y, int r, int g, int b)
        {
            if ((x > imageWidth) || (y > imageHeight) || (((imageStride * y) + (bytesPerPixel * x) + 2) > (imageBytes.Length - 1)))
                return false;
            imageBytes[(imageStride * y) + (bytesPerPixel * x) + 2] = (byte)r;
            imageBytes[(imageStride * y) + (bytesPerPixel * x) + 1] = (byte)g;
            imageBytes[(imageStride * y) + (bytesPerPixel * x)] = (byte)b;
            return true;
        }
    }
}
